package com.example.design.函数式编程.exercise;


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class Exercise01 {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);


        // 练习1
        List<Integer> filter = filter(list);
        List<Integer> filter1 = filter(list, number -> (number & 1) == 0);

        // 练习2
        List<String> map = map(list);
        List<String> map1 = map(list, number -> String.valueOf(number));


        // 练习3
        consumer(list, number-> System.out.println(number));

        // 练习4
        List<Integer> supply = supply(5, () -> ThreadLocalRandom.current().nextInt());
        System.out.println(supply);
    }


    /**
     * 练习1：把下列方法，可能存在变化的部分，抽象为函数，从外界传递进来
     */
    static List<Integer> filter(List<Integer> list) {
        List<Integer> result = new ArrayList<>();
        for (Integer number : list) {
            if ((number & 1) == 0) {
                result.add(number);
            }
        }
        return result;
    }

    /**
     * 练习1答案
     *
     * (number & 1) == 0核心逻辑,推出入参是Integer, 出参是boolean，使用Predicate
     */
    static List<Integer> filter(List<Integer> list, Predicate<Integer> predicate) {
        List<Integer> result = new ArrayList<>();
        for (Integer number : list) {
            if (predicate.test(number)) {
                result.add(number);
            }
        }
        return result;
    }


    /**
     * 练习2：将数字转为字符串
     */
    static List<String> map(List<Integer> list) {
        List<String> result = new ArrayList<>();
        for (Integer number : list) {
            result.add(String.valueOf(number));
        }
        return result;
    }

    /**
     * 练习2答案：String.valueOf(number)核心逻辑, 入参Integer,出参String,有入参有出参，且入参出参不一样，用Function
     *
     */
    static List<String> map(List<Integer> list, Function<Integer, String> function) {
        List<String> result = new ArrayList<>();
        for (Integer number : list) {
            result.add(function.apply(number));
        }
        return result;
    }


    /**
     * 练习3
     */
    static void consumer(List<Integer> list, Consumer<Integer> consumer) {
        for (Integer i : list) {
            consumer.accept(i);
        }
    }

    /**
     * 练习4
     */
    static List<Integer> supply(int count, Supplier<Integer> supplier) {
        List<Integer> result = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            result.add(supplier.get());
        }
        return result;
    }
}
